from helpFunc import *
import os,time,json
import sys
from collections import deque
import logging
from logging.handlers import RotatingFileHandler
try:
    os.mkdir('serLog')
except:
    pass
logger = logging.getLogger('tous')
handler = RotatingFileHandler('tous.log', maxBytes=10*1024, backupCount=1)
formatter = logging.Formatter("%(asctime)s %(message)s",
                              "%Y-%m-%d %H:%M:%S")
handler.setFormatter(formatter)
logger.addHandler(handler)


def xx(maxConn, cachePeerConn,ssPort,bufsize,oneLen,tLen,effTime,inter,ports,k):    
    pp =  findNPorts(2,ty=socket.SOCK_STREAM)
    t = tcpRePeer(pp[0],pp[1],maxConn,cachePeerConn,ssPort,bufsize)
    t.start(oneLen,tLen,effTime,inter,ports,k)      
import sys
    
if __name__ == '__main__':
    runningPath = os.path.split(os.path.realpath(__file__))[0]
    print (runningPath)      
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)     
    if relayMode:
        sock.bind(('0.0.0.0',relayModePort))
    else:
        sock.bind(('0.0.0.0',server_port))
    usedMap = {}
    usedQ = deque()    
    while True:
        data, addr = sock.recvfrom(udpReadLen)
        print(data,addr)
        w = structWrapper(data)
        k = w.readArr(len(con_key))
        if k!=con_key:
            continue
        id = w.readArr(16)  
        needSleep = False
        if id not in usedMap:
            needSleep = True
            num = w.readDWord()
            kLen = w.readByte()
            k  = w.readArr(kLen)
            maxConn = w.readDWord()
            cachePeerConn = w.readDWord()
            ssPort = w.readDWord()      
            oneLen = w.readDWord()
            tLen = w.readDWord()
            bufsize = w.readDWord()
            effTime = w.readDouble()
            inter = w.readDouble()
            ports = findNPorts(num)                
            m = {}
            m['maxConn'] = maxConn
            m['cachePeerConn'] = cachePeerConn
            m['ssPort'] = ssPort           
            m['oneLen'] = oneLen
            m['tLen'] = tLen
            m['bufsize'] = bufsize
            m['effTime'] = effTime
            m['inter'] = inter
            m['ports'] = ports 
            m['key'] = k.decode()
            if isWindows:    
                from conns import *
                from multiprocessing import *
                p = Process(target=xx, args=(maxConn, cachePeerConn,ssPort,bufsize,
                                              oneLen,tLen,effTime,inter,ports,k))                
                p.start()
            else:
                import base64,json
                j = json.dumps(m)
                s = base64.b64encode(j.encode())
                ex = sys.executable      
                os.system('nohup %s %s/conns.py %s >/dev/null &'%(ex,runningPath,s.decode()))    
                if relayMode and ssPort==con_localPort:
                    os.system('fuser %s/tcp>a.txt'%ssPort)
                    f = open('a.txt')
                    pp = f.read()
                    f.close()
                    os.system('kill -9 '+pp)
                    os.system('nohup %s %s/touc.py>/dev/null &'%(ex,runningPath))    
                    
            print ('start server:',ports)                
            logger.warning('add: %s keyLen: %s key:%s'%(str(addr),len(k),k.decode()))
            import struct
            re = b''
            for one in ports:
                re+= struct.pack('H',one)        
            usedMap[id] = re
            usedQ.append(id)            
            if len(usedMap)>10000:
                ss = usedQ.popleft()
                del usedMap[ss]
        print (addr)
        sock.sendto(id+usedMap[id],addr)
        if needSleep:
            time.sleep(1)
        
    
